package com.zhao.newcoder.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.UUID;

import com.alibaba.fastjson.JSON;
import com.zhao.newcoder.DTO.NewCoderDTO;
import com.zhao.newcoder.DTO.User;
import com.zhao.newcoder.DTO.UserCollectDTO;
import com.zhao.newcoder.Repository.CoderRepository;
import com.zhao.newcoder.Repository.ImgRepository;
import com.zhao.newcoder.Repository.NewCoderRepository;
import com.zhao.newcoder.Repository.UserCollectRepository;
import com.zhao.newcoder.Repository.UserRepository;
import com.zhao.newcoder.Soup.Result;
import com.zhao.newcoder.VO.ESCoderVo;
import com.zhao.newcoder.VO.NewCoderVO;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

@Api(value = "面经接口", tags = "面经列表和详情相关接口")
@CrossOrigin
@RestController
public class NewCoderController {

    private static SimpleDateFormat sf = null;

    @Autowired
    NewCoderRepository newCoderRepository;
    @Autowired
    UserRepository userRepository;
    @Autowired
    UserCollectRepository userCollectRepository;
    @Autowired
    ImgRepository imgRepository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Autowired
    CoderRepository coderRepository;
    @RequestMapping(value = "/newcoder",method = RequestMethod.GET)
    @ApiOperation(value = "面经列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNo", value = "页码"),
            @ApiImplicitParam(name = "pageSize", value = "每页数量"),
            @ApiImplicitParam(name = "type", value = "面经类型，Java,iOS等"),
            @ApiImplicitParam(name = "openid", value = "openid,userid传一个即可")

    })
    public Page getAll(@RequestParam(name = "pageNo",required = false) Integer pageNo,
    @RequestParam(name = "pageSize",required = false) Integer pageSize,
                                    @RequestParam(name = "type",required = false)String type,
                                    @RequestParam(name = "openid",required = false)String openid,
                                   @RequestParam(name = "keyword",required = false)String keyword
                                    ){


        if (pageNo == null){
            pageNo = 1;
        }
        if (pageSize==null){
            pageSize =10;
        }
        if (StringUtils.isNotBlank(keyword)){
            Pageable pageable = PageRequest.of(pageNo,pageSize);// （当前页， 每页记录数， 排序方式）
            //若索引不存在
            if(!elasticsearchTemplate.indexExists(ESCoderVo.class)){
                elasticsearchTemplate.deleteIndex(ESCoderVo.class);
                //创建索引
                elasticsearchTemplate.createIndex(ESCoderVo.class);
                List<NewCoderDTO> list = newCoderRepository.findAll();
                //将MySQL数据插入到ES
                if(!CollectionUtils.isEmpty(list)){
                    List<ESCoderVo> esList = JSON.parseArray(JSON.toJSONString(list), ESCoderVo.class);
                    coderRepository.saveAll(esList);
                }
            }

            BoolQueryBuilder builder = QueryBuilders.boolQuery();
            if (StringUtils.isNotBlank(type)){
                builder.must(QueryBuilders.matchQuery("type",type));
            }
            builder.should(QueryBuilders.matchQuery("title",keyword));
            builder.should(QueryBuilders.matchQuery("content",keyword));
            builder.should(QueryBuilders.matchQuery("label",keyword));

            SearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(builder)
                    .withPageable(pageable)
                    .build();

            Page<ESCoderVo> page = coderRepository.search(searchQuery);
            page.getContent().stream().forEach(x->{
                 NewCoderDTO coderDTO =   newCoderRepository.getOne(x.getId());
                x.setViewNum(coderDTO.getViewNum());
            });
            return page;
        }else {
            Sort sort = Sort.by(Sort.Direction.DESC,"createTime"); // 这里的"recordNo"是实体类的主键，记住一定要是实体类的属性，而不能是数据库的字段
            Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort); // （当前页， 每页记录数， 排序方式）
            NewCoderDTO dto = new NewCoderDTO();
            dto.setType(type);
            Example<NewCoderDTO> example=Example.of(dto);
            Page<NewCoderDTO> list = newCoderRepository.findAll(example,pageable);
            List<NewCoderVO> newCoderVOList = new ArrayList<>();
            list.getContent().stream().forEach(x->{
                NewCoderVO newCoderVO = new NewCoderVO();
                BeanUtils.copyProperties(x,newCoderVO);
                x.setContent(null);
                newCoderVOList.add(newCoderVO);
            });
            User user = userRepository.findUserByOpenid(openid);
            for (NewCoderVO x : newCoderVOList) {
                if (user!=null){
                    UserCollectDTO userCollect = userCollectRepository.findByUserIdAndAndInterviewId(user.getId(),x.getId());
                    if (userCollect!=null){
                        x.setIsCollect(true);
                    }else {
                        x.setIsCollect(false);
                    }
                }else {
                    x.setIsCollect(false);
                }
                Date d = new Date(Long.valueOf(x.getCreateTime()));
                sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                x.setCreateTime(sf.format(d));
                Random random = new Random();
                x.setImage_url(imgRepository.getOne(random.nextInt(150)+1).getImgUrl().trim());
            }
            return  new PageImpl<>(newCoderVOList, pageable, list.getTotalElements());
        }
    }





    @ApiOperation(value = "面经详情保存")
    @PostMapping(value = "/newcoder/save")
    public Result<NewCoderDTO> getNewCoder(@ApiParam("面经对象") @RequestBody NewCoderDTO dto){
        Random random = new Random();
        Integer id =  random.nextInt(400000);
        newCoderRepository.findById(Long.valueOf(id));
        dto.setId(Long.valueOf(id));
        newCoderRepository.save(dto);


        return new Result(200,"保存成功",dto);
    }
    @ApiOperation(value = "面经搜索")
    @GetMapping(value = "/newcoder/search")
    public Page<ESCoderVo> search(@RequestParam(name = "pageNo",required = false) Integer pageNo,
                                  @RequestParam(name = "pageSize",required = false) Integer pageSize,
                                  @RequestParam(name = "keyword",required = false)String keyword,
                                  @RequestParam(name = "type",required = false)String type
                                  ){
        if (pageNo == null){
            pageNo = 1;
        }
        if (pageSize==null){
            pageSize =10;
        }
        Pageable pageable = PageRequest.of(pageNo,pageSize);// （当前页， 每页记录数， 排序方式）
        //若索引不存在
        if(!elasticsearchTemplate.indexExists(ESCoderVo.class)){
            elasticsearchTemplate.deleteIndex(ESCoderVo.class);
            //创建索引
            elasticsearchTemplate.createIndex(ESCoderVo.class);
            List<NewCoderDTO> list = newCoderRepository.findAll();
            //将MySQL数据插入到ES
            if(!CollectionUtils.isEmpty(list)){
                List<ESCoderVo> esList = JSON.parseArray(JSON.toJSONString(list), ESCoderVo.class);
                coderRepository.saveAll(esList);
            }
        }

        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        if (StringUtils.isNotBlank(type)){
            builder.must(QueryBuilders.matchQuery("type",type));
        }
        builder.should(QueryBuilders.matchQuery("title",keyword));
        builder.should(QueryBuilders.matchQuery("content",keyword));
        builder.should(QueryBuilders.matchQuery("label",keyword));

        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(builder)
                .withPageable(pageable)
                .build();

        Page<ESCoderVo> page = coderRepository.search(searchQuery);
        return page;

    }




    @ApiOperation(value = "面经详情")
    @ApiImplicitParam(name = "id", value = "面经id")
    @RequestMapping(value = "/newcoderdetail",method = RequestMethod.GET)
    public NewCoderVO getNewCoder(@RequestParam(name ="id") Long id,
                                  @RequestParam(name = "openid",required =false) String openid){
        NewCoderDTO  dto = newCoderRepository.findById(id).get();
        dto.setViewNum(dto.getViewNum()+1);
        newCoderRepository.save(dto);
        NewCoderVO vo = new NewCoderVO();
        BeanUtils.copyProperties(dto,vo);
        Date d = new Date(Long.valueOf(dto.getCreateTime()));
        sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        vo.setCreateTime(sf.format(d));
        User user = userRepository.findUserByOpenid(openid);
        if(user!=null) {
            UserCollectDTO userCollectDTO =   userCollectRepository.findByUserIdAndAndInterviewId(user.getId(), id);
            if (userCollectDTO!=null){
                vo.setIsCollect(true);
            }else {
                vo.setIsCollect(false);
            }

        }else{
            vo.setIsCollect(false);
        }
        Random random = new Random();
        vo.setImage_url(imgRepository.getOne(random.nextInt(150)+1).getImgUrl().trim());

        return vo;
    }
    @ApiOperation(value = "面经收藏")
    @ApiImplicitParam(name = "id", value = "面经id")
    @RequestMapping(value = "/collect",method = RequestMethod.GET)
    public UserCollectDTO collect(@RequestParam(name = "id") Long id,
                                  @RequestParam(name = "openid",required = false) String openid
    ){

        User user = userRepository.findUserByOpenid(openid);
        UserCollectDTO userCollect= userCollectRepository.findByUserIdAndAndInterviewId(user.getId(),id);
        if (userCollect!=null){
            userCollectRepository.delete(userCollect);
            return  null;
        }else {
            userCollect = new UserCollectDTO();
            userCollect.setId(UUID.randomUUID().toString());
            userCollect.setInterviewId(id);
            userCollect.setUserId(user.getId());
            userCollect.setCreateTime(new Date());
            userCollectRepository.save(userCollect);
            return userCollect;
        }
    }


    @ApiOperation(value = "我的收藏")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNo", value = "页码"),
            @ApiImplicitParam(name = "pageSize", value = "每页数量"),
            @ApiImplicitParam(name = "openid", value = "openid,userid传一个即可")

    })
    @RequestMapping(value = "/myCollect",method = RequestMethod.GET)
    public Page<NewCoderVO> myCollect(@RequestParam(name = "pageNo",required = false) Integer pageNo,
                                    @RequestParam(name = "pageSize",required = false) Integer pageSize,
                                  @RequestParam(name = "openid",required = false) String openid
    ){

        User user = userRepository.findUserByOpenid(openid);
        if (user!=null){
            Sort sort = Sort.by(Sort.Direction.DESC,"createTime"); // 这里的"recordNo"是实体类的主键，记住一定要是实体类的属性，而不能是数据库的字段
            Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort); // （当前页， 每页记录数， 排序方式）
            UserCollectDTO dto = new UserCollectDTO();
            dto.setUserId(user.getId());
            Example<UserCollectDTO> example=Example.of(dto);
            Page<UserCollectDTO> userCollects= userCollectRepository.findAll(example,pageable);
            List<NewCoderVO> newCoderVOList = new ArrayList<>();
            userCollects.getContent().stream().forEach(x->{
                NewCoderVO newCoderVO = new NewCoderVO();
                NewCoderDTO  newCoder = newCoderRepository.getOne(x.getInterviewId());
                BeanUtils.copyProperties(newCoder,newCoderVO);
                newCoderVO.setIsCollect(true);
                Random random = new Random();
                newCoderVO.setImage_url(imgRepository.getOne(random.nextInt(150)+1).getImgUrl().trim());

                newCoderVOList.add(newCoderVO);

            });
            return  new PageImpl<>(newCoderVOList, pageable, userCollects.getTotalElements());

        }
        return  null;
    }


}
